package com.mycode.chapter02.processor;

import com.mycode.chapter02.common.Constants;
import com.mycode.chapter02.server.Request;
import com.mycode.chapter02.server.RequestFacade;
import com.mycode.chapter02.server.Response;
import com.mycode.chapter02.server.ResponseFacede;

import javax.servlet.Servlet;
import java.io.File;
import java.io.IOException;
import java.net.URL;
import java.net.URLClassLoader;
import java.net.URLStreamHandler;

// Servlet 处理器
public class ServletProcessor2 implements Processor{

    @Override
    public void process(Request request, Response response) {
        String uri = request.getUri();
        // 获取要访问的 Servlet 的类名
        String servletName = uri.substring(uri.lastIndexOf("/") + 1);
        // 创建类载入器
        URLClassLoader loader = null;

        try {

            URL[] urls = new URL[1];
            URLStreamHandler streamHandler = null;
            File classPath = new File(Constants.WEB_ROOT);
            // 指定加载的目录位置
            // 生成仓库后会调用 org.apache.catalina.startup.ClassLoaderFactory. createClassLoader()
            String repository = (new URL("file", null, classPath.getCanonicalPath() + File.separator)).toString() ;
            // 生成URL对象后会调用 org.apache.catalina.loader.StandardClassLoader class. addRepository()
            urls[0] = new URL(null, repository, streamHandler);
            // 实例化 URLClassLoader 载入器
            loader = new URLClassLoader(urls);
        }
        catch (IOException e) {
            System.out.println(e);
        }
        Class myClass = null;
        try {
            // 加载对应的 Servlet 类
            myClass = loader.loadClass(servletName);
        }
        catch (ClassNotFoundException e) {
            System.out.println(e);
        }

        Servlet servlet = null;
        RequestFacade requestFacade = new RequestFacade(request);
        ResponseFacede responseFacede = new ResponseFacede(response);
        try {
            servlet = (Servlet) myClass.newInstance();
            servlet.service(requestFacade, responseFacede);

        }
        catch (Exception e) {
            System.out.println(e);
        }
        catch (Throwable e) {
            System.out.println(e);
        }
    }
}
